package caobject;

import java.io.File;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.io.Serializable;
import java.util.ArrayList;
import java.util.Scanner;

/**
 * The Manuscript Class.
 * @author Tom Netzer
 * @author Brian Luger (Added toString(), hashCode, and 
 * equals() methods.)
 * @author Chandni Sabhaya (Added addReviewer(), getReviews(), getReviewers(),
 * findReviewIndexByUser(final User the_user) methods. 
 * Modified  addReview() method completely. )
 * @version 1
 */
public class Manuscript implements Serializable, Cloneable {

	/**
	 * Generated SV-UID
	 */
	private static final long serialVersionUID = -2039086221645386989L;

	/**
	 * The default status of every manuscript.
	 */
	private String my_status = "UNDECIDED";
	
	private String my_author;
	
	private String my_title;
	
	private String my_text;
	
	// A list containing all of the reviews for the manuscript.
	private ArrayList<Review> my_reviews;
	
	// A list containing all of the reviewers for the manuscript.
	private ArrayList<User> my_reviewers;
	
	//Manuscript Constructor
	public Manuscript(String the_author, String the_title,
			String the_text) {
		my_author = the_author;
		my_title = the_title;
		my_text = the_text;
		my_reviews = new ArrayList<Review>();
		my_reviewers = new ArrayList<User>();
	}
	
	public void setAuthor(String the_author) {
		my_author = the_author;
	}
	
	public String getAuthor() {
		return my_author;
	}
	
	public void setTitle(String the_title) {
		my_title = the_title;
	}
	
	public String getTitle() {
		return my_title;
	}
	
	public void setText(String the_text) {
		my_text = the_text;
	}
	
	public String getText() {
		return my_text;
	}
	
	/**
	 * Returns the status of a manuscript.
	 * @return the current status.
	 */
	public String getStatus() {
		return my_status;
	}
	
	/**
	 * Sets the status of a manuscript.
	 * @param new_status is the status the manuscript
	 * will be changed to.
	 * @param the_user is the user of the manuscript.
	 * <pre> default_status is not null.
	 */
	public void setStatus(String the_status,
			User the_user) {
		if(the_user.getcurrentRole().equals
				(EnumRole.PROGRAMCHAIR)){
		my_status = the_status;
		}
	}
	
	//Gets the text of a file.
	public StringBuilder getText(final String the_text) 
		throws FileNotFoundException, IOException {
		// Wrap a file scanner so we can use Scanner 
		// methods on the file.
		Scanner file = new Scanner(new File (the_text));
		StringBuilder word = new StringBuilder();

		while(file.hasNext()) { //read file word by word
			word.append(file.next() + " ") ;		
		}
		file.close();
		return word;
	}
	
	/**
	 * Adds a review to the list associated with a manuscript. Since each
	 * Manuscript can have only one review, Adding another new review for 
	 * the same paper removes the old review. 
	 * 
	 * @param the_user
	 * @param stringBuilder	 * 
	 * 
	 * <pre> The user is a reviewer && the user is one of the
	 * users assigned to review the manuscript.
	 * <post> ArrayList my_reviews + 1.
	 */
	public void addReview(User the_user, String the_text) {
		// remove any existing review by this user
		int indexOfExistingReview = findReviewIndexByUser(the_user);
		if(indexOfExistingReview >= 0) {
			my_reviews.remove(indexOfExistingReview);
		}
		
		// add a new review
		Review review = new Review(the_user, my_title, the_text);
		my_reviews.add(review);
	}
	
	/**
	 * This method returns -1 if no review is found by user, otherwise it 
	 * returns the index of review by user. 
	 *  
	 * @param the_user the reviewer 
	 * @return -1 if no review index found by user, otherwise positive number 
	 */
	private int findReviewIndexByUser(final User the_user) {
		int index = -1;
		for(int i = 0; i < my_reviews.size(); i++) {
			Review review = my_reviews.get(i);
			
			if(review.getReviewerName().equals(the_user.getUserName())) {
				index = i;
				break;
			}
		}
		return(index);
	}
	
	//gets the number of reviews currently in the list
	public int getReviewsSize(){
		return my_reviews.size();
	}

	public ArrayList<Review> getReviews() {
		return my_reviews;
	}
	
	/** Adds a reviewer to the list associated with a manuscript.
	 * 
	 * @param the_user
	 * <pre> The user is a reviewer && the user is one of the
	 * users assigned to review the manuscript.
	 * <post> ArrayList my_reviewers + 1.
	 */
	public void addReviewer(User the_user) {
		my_reviewers.add(the_user);
	}
	
	//gets the list of reviewers  
	public ArrayList<User> getReviewers(){
		return my_reviewers;
	}
	
	/**
	 * Manuscript equals() method.
	 */
	@Override
	public boolean equals(final Object otherObject) {
		// A quick test to see if the objects are identical.
		if (this == otherObject) {
			return true;
		}
		
		// Must return false if the explicit parameter is 
		// null
		if (otherObject == null) {
			return false;
		}
		
		// If the classes don't match, they can't be equal,
		if(getClass() != otherObject.getClass()) {
			return false;
		}
		
		// other must be a non-null Manuscript.
		Manuscript other = (Manuscript) otherObject;
		
		return my_author.equalsIgnoreCase(other.my_author)
		&& my_title.equalsIgnoreCase(other.my_title)
		&& my_text.equalsIgnoreCase(other.my_text);
	}
	
	/**
	 * Manuscript hashCode() method.
	 */
	@Override
	public int hashCode() {
		return toString().hashCode();
	}
	
	/**
	 * Manuscript toString() method.
	 */
	@Override
	public String toString() {
		final StringBuilder sb = new StringBuilder();
		
		sb.append("Author: " + my_author + "\n\n");
		sb.append("Title: " + my_title + "\n\n");
		sb.append("Text: \n\n");
		sb.append(my_text + "\n\n\n");
		
		return sb.toString();
	}
	
	//clones the manuscript
	public Object clone() {
	     Manuscript man;
	    try {
	      man = (Manuscript) super.clone();
	    } catch (CloneNotSupportedException e) {
	      return null;  //will never happen
	    }
	    return man;
	}
}
